package com.bestow.basic.service.impl;

import java.io.*;
import java.util.*;

import com.alibaba.fastjson.JSONObject;
import com.bestow.basic.domain.FndAtmAttachment;
import com.bestow.basic.mapper.FndAtmAttachmentMapper;
import com.bestow.common.utils.DateUtils;
import com.bestow.dox4j.component.BookMarkReplaceComponent;
import org.apache.commons.lang3.StringUtils;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bestow.basic.mapper.FndAtmAttachmentMultiMapper;
import com.bestow.basic.domain.FndAtmAttachmentMulti;
import com.bestow.basic.service.IFndAtmAttachmentMultiService;

/**
 * 附件关联Service业务层处理
 *
 * @author liliu
 * @date 2022-09-22
 */
@Service
public class FndAtmAttachmentMultiServiceImpl implements IFndAtmAttachmentMultiService {

    private static final String HLS_DOC_FILE_TEMPLET = "hls_doc_file_templet";

    @Autowired
    private FndAtmAttachmentMapper fndAtmAttachmentMapper;

    @Autowired
    private BookMarkReplaceComponent bookMarkReplaceComponent;

    @Autowired
    private FndAtmAttachmentMultiMapper fndAtmAttachmentMultiMapper;

    /**
     * 查询附件关联
     *
     * @param recordId 附件关联主键
     * @return 附件关联
     */
    @Override
    public FndAtmAttachmentMulti selectFndAtmAttachmentMultiByRecordId(Long recordId) {
        return fndAtmAttachmentMultiMapper.selectFndAtmAttachmentMultiByRecordId(recordId);
    }

    /**
     * 查询附件关联列表
     *
     * @param fndAtmAttachmentMulti 附件关联
     * @return 附件关联
     */
    @Override
    public List<FndAtmAttachmentMulti> selectFndAtmAttachmentMultiList(FndAtmAttachmentMulti fndAtmAttachmentMulti) {
        return fndAtmAttachmentMultiMapper.selectFndAtmAttachmentMultiList(fndAtmAttachmentMulti);
    }

    /**
     * 新增附件关联
     *
     * @param fndAtmAttachmentMulti 附件关联
     * @return 结果
     */
    @Override
    public int insertFndAtmAttachmentMulti(FndAtmAttachmentMulti fndAtmAttachmentMulti) {
        fndAtmAttachmentMulti.setCreateTime(DateUtils.getNowDate());
        return fndAtmAttachmentMultiMapper.insertFndAtmAttachmentMulti(fndAtmAttachmentMulti);
    }

    /**
     * 修改附件关联
     *
     * @param fndAtmAttachmentMulti 附件关联
     * @return 结果
     */
    @Override
    public int updateFndAtmAttachmentMulti(FndAtmAttachmentMulti fndAtmAttachmentMulti) {
        fndAtmAttachmentMulti.setUpdateTime(DateUtils.getNowDate());
        return fndAtmAttachmentMultiMapper.updateFndAtmAttachmentMulti(fndAtmAttachmentMulti);
    }

    /**
     * 批量删除附件关联
     *
     * @param recordIds 需要删除的附件关联主键
     * @return 结果
     */
    @Override
    public int deleteFndAtmAttachmentMultiByRecordIds(Long[] recordIds) {
        return fndAtmAttachmentMultiMapper.deleteFndAtmAttachmentMultiByRecordIds(recordIds);
    }

    /**
     * 删除附件关联信息
     *
     * @param recordId 附件关联主键
     * @return 结果
     */
    @Override
    public int deleteFndAtmAttachmentMultiByRecordId(Long recordId) {
        return fndAtmAttachmentMultiMapper.deleteFndAtmAttachmentMultiByRecordId(recordId);
    }

    /**
     * 通过生成文件，返回文件id
     *
     * @param params
     * @throws Exception
     */
    public Long getDocAttachmentByBookmark(Map<String, Object> params) throws Exception {
        Long attachmentId = null;

        Long templetId = Long.valueOf(String.valueOf(params.get("templetId")));
        String tableName = (String)params.get("tableName");
        String tablePkValue = (String) params.get("tablePkValue");

        try {
            FndAtmAttachmentMulti fndAtmAttachmentMulti = new FndAtmAttachmentMulti();
            fndAtmAttachmentMulti.setTableName(HLS_DOC_FILE_TEMPLET);
            fndAtmAttachmentMulti.setTablePkValue(templetId.toString());
            fndAtmAttachmentMulti = fndAtmAttachmentMultiMapper.selectFndAtmAttachmentMultiList(fndAtmAttachmentMulti).get(0);

            FndAtmAttachment fndAtmAttachment = fndAtmAttachmentMapper.selectFndAtmAttachmentByAttachmentId(fndAtmAttachmentMulti.getAttachmentId());
            if (Objects.isNull(fndAtmAttachment) || StringUtils.isBlank(fndAtmAttachment.getFilePath())) {
                throw new IOException("未找到单据模板!" );
            }

            File file = new File(fndAtmAttachment.getFilePath());
            if (!file.exists()) {
                throw new IOException("单据生成失败!" );
            }

            if (file.length() > 0) {
                FileInputStream fileInputStream = new FileInputStream(file);
                String copyFilePath = fndAtmAttachment.getFilePath().concat("_back_" ).concat(UUID.randomUUID().toString());
                copyModel(copyFilePath, fileInputStream);
                FileInputStream copyFileInputStream = new FileInputStream(copyFilePath);

                this.createDocx(copyFileInputStream, new File(copyFilePath), new HashMap<String, Object>());

                FndAtmAttachmentMulti copyFndAtmAttachmentMulti = new FndAtmAttachmentMulti();
                copyFndAtmAttachmentMulti.setTableName(tableName);
                copyFndAtmAttachmentMulti.setTablePkValue(tablePkValue);
                List<FndAtmAttachmentMulti> fndAtmAttachmentMultis = fndAtmAttachmentMultiMapper.selectFndAtmAttachmentMultiList(copyFndAtmAttachmentMulti);

                if (!fndAtmAttachmentMultis.isEmpty() && fndAtmAttachmentMultis.size() > 0) {
                    copyFndAtmAttachmentMulti = fndAtmAttachmentMultis.get(0);
                    FndAtmAttachment copyFndAtmAttachment = fndAtmAttachmentMapper.selectFndAtmAttachmentByAttachmentId(copyFndAtmAttachmentMulti.getAttachmentId());
                    copyFndAtmAttachment.setFilePath(copyFilePath);
                    fndAtmAttachmentMapper.updateFndAtmAttachment(copyFndAtmAttachment);
                } else {
                    this.fndAtmAttachmentMultiMapper.insertFndAtmAttachmentMulti(copyFndAtmAttachmentMulti);

                    FndAtmAttachment copyFndAtmAttachment = new FndAtmAttachment();
                    copyFndAtmAttachment.setFileName("xxx.docx" );
                    /*if (expensesApp != null) {
                        conDocFile.setFileName("资金用款申请单-" + expensesApp.getExpensesNumber() + ".docx");
                    } else {
                        copyFndAtmAttachment.setFileName("资金用款申请单.docx");
                    }*/

                    copyFndAtmAttachment.setSourceTypeCode("fnd_atm_attachment_multi" );
                    copyFndAtmAttachment.setSourcePkValue(copyFndAtmAttachmentMulti.getRecordId().toString());
                    copyFndAtmAttachment.setFilePath(copyFilePath);
                    copyFndAtmAttachment.setFileTypeCode(".docx" );
                    copyFndAtmAttachment.setFileSize(0L);
                    this.fndAtmAttachmentMapper.insertFndAtmAttachment(copyFndAtmAttachment);
                    copyFndAtmAttachmentMulti.setAttachmentId(copyFndAtmAttachment.getAttachmentId());
                    this.fndAtmAttachmentMultiMapper.updateFndAtmAttachmentMulti(copyFndAtmAttachmentMulti);
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return attachmentId;
    }

    public void createDocx(InputStream is, File file, Map<String, Object> params) throws Exception {
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(is);
        wordMLPackage = this.bookMarkReplaceComponent.docxCreateBookMarkReplaceWithText(wordMLPackage, params);
        wordMLPackage.save(file);
    }

    private static synchronized void copyModel(String filePath, InputStream is) throws IOException {
        FileOutputStream fos = new FileOutputStream(filePath);
        byte[] b = new byte[1024];

        int readData;
        while ((readData = is.read(b)) != -1) {
            fos.write(b, 0, readData);
        }

        fos.flush();
        is.close();
        fos.close();
    }
}
